<?php
/**
 * Here the class '\UF\ArgumentException' is defined.
 *
 * @category   UniKap-Framework
 * @package    Core
 * @subpackage Exceptions
 * @author     Ulf -UniKado- Kadner <ulfikado@gmail.com>
 * @since      2014-03-29 16:17
 * @version    0.1
 */

namespace UF
{

    /**
     * This exception is used if a method or function is called with a invalid argument/parameter.
     *
     * The class extends {@see \UF\Exception}
     *
     * @since      v0.1
     */
    class ArgumentException extends \UF\Exception
    {

        # <editor-fold defaultstate="collapsed" desc="P R O T E C T E D   F I E L D S">

        /**
         * The argument/parameter name.
         *
         * @var string
         * @since  v0.1
         */
        protected $argumentName;
        /**
         * The name of the function or method.
         *
         * @var string
         * @since  v0.1
         */
        protected $functionName;

        # </editor-fold>

        # <editor-fold defaultstate="collapsed" desc="C O N S T R U C T O R">

        /**
         * Inits a new instance
         *
         * @param string     $arg      The argument/parameter name.
         * @param mixed      $value    The argument/parameter value
         * @param string     $message  A optional error message
         * @param int        $code     The optional error code (Defaults to \E_USER_ERROR)
         * @param \Exception $previous A optional previous exception
         * @since  v0.1
         */
        public function __construct( $arg, $value, $message = null, $code = \E_USER_ERROR, \Exception $previous = null )
        {
            $trace = \debug_backtrace();
            $lidx  = \count( $trace ) - 1;
            $fn = ( empty( $trace[$lidx]['class'] )    ? '' : $trace[$lidx]['class'] ).
                  ( empty( $trace[$lidx]['type'] )     ? '' : $trace[$lidx]['type']  ) .
                  ( empty( $trace[$lidx]['function'] ) ? '' : $trace[$lidx]['function'] );
            parent::__construct(
                \UF\_3( '_core', 'Argument $%s%s uses a invalid value of type %s!',
                    \ltrim( $arg, '$' ),
                    ( empty( $fn ) ? '' : \UF\_( '_core', ' of ' ) . $fn . '(…)' ),
                    self::GetTypeStr( $value ) .
                    ( empty( $message ) ? '' : ( ' ' . $message ) ) ),
                $code, $previous );
            $this->argumentName = $arg;
            $this->functionName = $fn;
        }

        # </editor-fold>

        # <editor-fold defaultstate="collapsed" desc="P U B L I C   G E T T E R   M E T H O D S">

        /**
         * Returns the argument/parameter name.
         *
         * @return string
         * @since  v0.1
         */
        public final function getArgumentName()
        {
            return $this->argumentName;
        }

        /**
         * Returns the argument/parameter value.
         *
         * @return mixed
         * @since  v0.1
         */
        public final function getFunctionName()
        {
            return $this->functionName;
        }

        # </editor-fold>

        # <editor-fold defaultstate="collapsed" desc="P R O T E C T E D   S T A T I C   M E T H O D S">

        /**
         * Returns a string, representing the $value.
         *
         * @param mixed $value
         * @return string
         * @since  v0.1
         */
        protected static function GetTypeStr( $value )
        {
            if ( \is_null( $value ) ) { return 'NULL'; }
            if ( \is_resource( $value ) ) { return \get_resource_type( $value ) . '-Resource'; }
            if ( \is_string( $value ) )
            {
                if ( \strlen($value) > 80)
                    return \UF\_1( '_core', '%s with value (', 'string' ) . \substr($value, 0, 78) . '…)';
                return \UF\_1( '_core', '%s with value (', 'string' ) . $value . ')';
            }
            if ( \is_bool( $value ) )
                return \UF\_1( '_core', '%s with value (', 'boolean' ) . ($value ? 'true' : 'false') . ')';
            if ( \is_int( $value ) )    return \UF\_1( '_core', '%s with value (', 'integer' ) . $value . ')';
            if ( \is_float( $value ) )  return \UF\_1( '_core', '%s with value (', 'float' ) . $value . ')';
            if ( \is_double( $value ) ) return \UF\_1( '_core', '%s with value (', 'double' ) . $value . ')';
            if ( \is_object( $value ) ) return \get_class( $value );
            return \gettype( $value );
        }

        # </editor-fold>

    }

}

